﻿using System;
using Newtonsoft.Json;
using Rebazza.RegexGame.MessageHandlers;
using Rebazza.Server;
using Rebazza.Server.Entities;
using Rebazza.Server.MessageHandlers;
using Rebazza.Server.Utils;
using Rebazza.Utils.Enums;

namespace Rebazza.RegexGame.Entities
{
    public class GameServer : GameServerDecorator
    {
        private const int MIN_USER_COUNT = 1;
        private const int MAX_USER_COUNT = 2;

        private readonly RoomedGameServer gameServer;
        private readonly BaseHandler baseHandler;
        private readonly GameHandler gameHandler;

        public GameServer(int gamePort, int roomCount) : base(gamePort)
        {
            gameServer = new RoomedGameServer(gamePort, roomCount, MIN_USER_COUNT, MAX_USER_COUNT);
            baseHandler = new BaseHandler();
            gameHandler = new GameHandler();
        }

        public override void Start()
        {
            gameServer.Start();
            ListenServer();
        }

        public override void Stop()
        {
            UnsubscribeFromTheServer();
            gameServer.Stop();
        }

        private void ListenServer()
        {
            gameServer.ClientConnected += OnClientConnected;
            gameServer.ClientDisconnected += OnClientDisconnected;
            gameServer.ReceiveFromClient += OnReceiveFromClient;
            gameServer.SendToClient += OnSendToClient;
        }

        private void UnsubscribeFromTheServer()
        {
            gameServer.ClientConnected -= OnClientConnected;
            gameServer.ClientDisconnected -= OnClientDisconnected;
            gameServer.ReceiveFromClient -= OnReceiveFromClient;
            gameServer.SendToClient -= OnSendToClient;
        }

        public static void OnClientConnected(object sender, ServerEventArgs e)
        {
            // TODO: NotImplemented
        }

        public static void OnClientDisconnected(object sender, ServerEventArgs e)
        {
            // TODO: NotImplemented
        }

        public void OnReceiveFromClient(object sender, ServerEventArgs e)
        {
            try
            {
                var json = e.User.Context.DataFrame.ToString();
                var message = JsonConvert.DeserializeObject<Message>(json);

                Message response;
                switch (message.Mode)
                {
                    case CommandMode.Base:
                        response = baseHandler.Handle(message, gameServer, e.User);
                        break;
                    case CommandMode.Game:
                        response = gameHandler.Handle(message);
                        break;
                    default:
                        response = Messenger.GetErrorMessage(e.User.Context, "Bad command mode.");
                        break;
                }

                e.User.Send(response);
            }
            catch (Exception exception)
            {
                var response = Messenger.GetErrorMessage(e.User.Context, exception.Message);
                e.User.Send(response);
            }
        }

        public static void OnSendToClient(object sender, ServerEventArgs e)
        {
            // TODO: NotImplemented
        }
    }
}
